/*    crw.c    */
#include <stdlib.h>
#include "crw.h"
#include "key.h"
#include "data.h"
#include "bool.h"

struct slist
{
    key k;
    data d;
    struct slist *next;
};

typedef struct slist *list;

struct scrw
{
    list pie;
    list Pvisor;
    int con;
    int size;
};


crw
crw_create(void)
{
    crw c;
    c=(crw)malloc(sizeof(struct scrw));
    
    c->pie=NULL;
    c->Pvisor=NULL;
    c->con=0;
		c->size=0;
    
    return c;
}

crw
crw_arr(crw c)
{
		if(c->pie!=NULL)
    {
			c->Pvisor=c->pie;
			c->con=1; /* para cuando tenga tan solo un elemento */
			
    }
	return c;
}
/*
  PRE: que la lista no sea vacia.
  POS: c->Pvisor esta aputando al ultimo lugar, con lo que
  "el visor" se encuentra en el primer lugar.
*/

crw
crw_av(crw c)/*
{
    c->Pvisor=c->Pvisor->next;
}*/
/* Esto es si queremos que no la re-arranque al llegar al final*/
{     
    if(!(crw_fin(c)))
    {
			c->con=(c->con)+1;
			c->Pvisor=c->Pvisor->next;
    }
    else
    {
		c->Pvisor=NULL;
		
    }
	return c;
}

key
crw_elecor_key(crw c)
{
    return(c->Pvisor->next->k);
}

data
crw_elecor_data(crw c)
{
    return(c->Pvisor->next->d);
}

crw
crw_insert(key k,data d, crw c)
{
    list ltemp;
    c->size=c->size+1;

    ltemp=(list)malloc(sizeof(list));

    ltemp->k = k;
 	  ltemp->d = d;

    if (crw_isempty(c))
		{	
			ltemp->next = ltemp;
  		c->pie = ltemp;
		}
		else
		{
			if (!(crw_isarr(c)))
				c=crw_arr(c);
	
			c->con=(c->con)+1;	
			ltemp->next = c->Pvisor->next;
     	c->Pvisor->next = ltemp;
/* Y ahora chananananan dejamos el visor en el nuevo mismo lugar */
       c->Pvisor = ltemp;
				
		}
		ltemp=NULL;
		return c;
}

bool
crw_fin(crw c)
{
    return(((c->size)+1)==(c->con));
}

crw
crw_del(crw c)
{
    list ltemp;
    key ktemp;
    data dtemp;
    
    dtemp = c->Pvisor->next->d;
    dtemp = data_destroy(dtemp);
    ktemp = c->Pvisor->next->k;
    ktemp = key_destroy(ktemp);

    ltemp = c->Pvisor->next;

    if( c->Pvisor->next == c->pie )
    {
			c->pie = c->Pvisor;
    }
    
    c->Pvisor->next = ltemp->next;
    
    free(ltemp);
		(c->con)--;
		(c->size)--;
	
		if (c->size==0)
			{
				c->pie=NULL;
				c->Pvisor=NULL;
		  }
		return c;
}

crw
crw_destroy(crw c)
{
		
		
/*    while(c->pie!=NULL)*/
		while(!(crw_isempty(c)))
    {
			
			c=crw_arr(c);
			c=crw_del(c);
    }
			free(c);
			c=NULL;
    return c;
}

bool
crw_isempty(crw c)
{
	return (c->pie==NULL);
}

bool
crw_isarr(crw c)
{
	return (c->Pvisor!=NULL);
}

/*    crw.c    */
int
crw_tam(crw c)
{
  return (c->size);
}

